﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

/*
 * Christiaan Rakowski
 * CFProxy - Content Filtering Proxy
 */

namespace CFProxy.FilterCode
{
	/// <summary>
	/// Base class for Filters
	/// </summary>
	class Filter
	{
		/// <summary>
		/// Backend for the property to make sure we never get a null on the HashSet.
		/// </summary>
		private HashSet<Regex> _regexes = new HashSet<Regex>();

		/// <summary>
		/// HashSet containing all the unique regular expressions for the rules of this Filter.
		/// </summary>
		public HashSet<Regex> Regexes
		{
			get { return _regexes; }
			set { _regexes = value; }
		}

		/// <summary>
		/// The Name of the filter
		/// </summary>
		public string Name { get; set; }

		/// <summary>
		/// Create a new filter based on the keyword file
		/// </summary>
		/// <param name="ruleFile">The keyword file for this filter</param>
		public Filter(string ruleFile)
		{
			LoadFile(ruleFile);
		}

		/// <summary>
		/// Loads rules for the filter from the file and creates Regex objects with those
		/// </summary>
		/// <param name="rulesFile">Path to the rules file</param>
		public void LoadFile(string rulesFile)
		{
			try
			{
				using (StreamReader reader = new StreamReader(rulesFile))
				{
					Name = reader.ReadLine();
					HashSet<string> rules = new HashSet<string>();
					string rule = reader.ReadLine();
					while (rule != null)
					{
						rules.Add(rule);
						rule = reader.ReadLine();
					}
					reader.Close();

					foreach (string s in rules)
					{
						Regex reg = new Regex(s, RegexOptions.Compiled);
						Regexes.Add(reg);
					}
				}
			}
			catch (Exception ex)
			{				
				throw ex;
			}
		}

		/// <summary>
		/// Check if the line entered matches a rule.
		/// </summary>
		/// <param name="line">The packet to check</param>
		/// <returns>True if the packet matched a rule, False if it did not</returns>
		public bool Check(string line)
		{
			foreach (Regex regex in Regexes)
			{
				if (regex.IsMatch(line))
				{
#if DEBUG
					Console.WriteLine(regex.Match(line).Value);
#endif
					return true;
				}
			}
			return false;
		}
	}
}
